Repository navigation
Conversation
kmcginnes
force-pushed
the
vite-plus
branch
from
September 29, 2026 22:45
898393d to
6cbeb9c
Compare
kmcginnes
force-pushed
the
vite-plus
branch
2 times, most recently
from
September 29, 2026 23:04
3b0105d to
17a6a55
Compare
kmcginnes
changed the base branch from
explicit-vitest-imports
to
remove-coverage
September 29, 2026 23:05
kmcginnes
force-pushed
the
vite-plus
branch
2 times, most recently
from
September 30, 2026 19:14
b74946b to
c791fbc
Compare
kmcginnes
force-pushed
the
vite-plus
branch
2 times, most recently
from
October 1, 2026 19:31
3c2e77c to
11e1ef5
Compare
kmcginnes
force-pushed
the
vite-plus
branch
2 times, most recently
from
October 13, 2026 20:56
4c38f97 to
a0457f2
Compare
kmcginnes
commented
Oct 13, 2026
kmcginnes
marked this pull request as ready for review
October 13, 2026 21:49
This was referenced Oct 13, 2026
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary
The lint config ignored every `*.config.{js,ts,mjs}` file, so
`vite-plus/prefer-vite-plus-imports` never saw the four `vite.config.ts`
files, which is where a stray `vite` or `vitest` import is most likely
to come back.
```diff
- ignorePatterns: ["**/*.config.{js,ts,mjs}", ".claude/"],
+ ignorePatterns: [".claude/"],
```
The configs already pass every rule, including the type-aware ones, so
nothing else changes.
## Evidence
**Before:** changing `packages/shared/vite.config.ts` to import from
`"vite"` passed `vp lint`.
**After:** the same change fails:
```
packages/shared/vite.config.ts:1:30: error vite-plus(prefer-vite-plus-imports): Use 'vite-plus' instead of 'vite' in Vite+ projects.
```
## Merge Danger
**Door:** two-way
**Impact:** contributors
Lint now covers 4 more files. No runtime or build change.
## Related
- Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary `pnpm checks` ran lint and format as two separate scripts. `vp check` runs both in one pass, so `checks` now calls it and keeps the `tsc` type check after it. ```diff - "checks": "pnpm run check:lint && pnpm run check:format && pnpm run check:types", + "checks": "vp check && pnpm run check:types", ``` `check:lint`, `check:format`, and `check:types` stay for running one check on its own. CI still calls `pnpm checks`. ## Evidence Each failure planted in `packages/shared/src/constants.ts` still fails `pnpm checks`: - **Lint** (`debugger;`): exit 1, `error: Lint issues found` - **Format** (`export const x = 1`): exit 1, `error: Formatting issues found` - **Types** (`const y: number = "s"`): exit 1, `TS2322: Type 'string' is not assignable to type 'number'` - **Clean tree:** exit 0 ## Merge Danger **Door:** two-way **Impact:** contributors Only the shape of the `pnpm checks` output changes. ## Related - Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary
Zed was formatting through an `external` command and had no lint server,
while the docs already ask Zed users to install `oxc-zed`. This switches
`.zed/settings.json` to the settings Vite+ generates for Zed, so
format-on-save and inline lint come from the oxfmt and oxlint language
servers, both reading `vite.config.ts`.
```diff
{
- "format_on_save": "on",
- "formatter": [{ "external": { "command": "pnpm", "arguments": ["exec", "vp", "fmt", "--stdin-filepath", "{buffer_path}"] } }],
"lsp": {
+ "oxlint": { "initialization_options": { "settings": { "run": "onType", "typeAware": true, ... } } },
+ "oxfmt": { "initialization_options": { "settings": { "fmt.configPath": "./vite.config.ts", "run": "onSave" } } },
"tailwindcss-language-server": { ... }
},
"languages": {
+ // one entry per language Vite+ formats (17), each using the oxfmt language server
+ // JavaScript also runs source.fixAll.oxc
"CSS": { "language_servers": ["tailwindcss-intellisense-css", "!vscode-css-language-server", "..."] }
}
}
```
The Tailwind `lsp` block and the CSS `language_servers` override are
kept from the old file. The CSS list gains `"..."` so the oxfmt and
oxlint servers still start for CSS; without it Zed runs only the servers
listed by name.
**Verified live:** in Zed with `oxc-zed`, format on save and inline
lint.
## Merge Danger
**Door:** two-way
**Impact:** Zed users
Without the `oxc-zed` extension, Zed no longer formats on save.
`docs/development.md` already tells Zed users to install it.
## Related
- Related to #2305
This was referenced Oct 14, 2026
Merged
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary
CI set up Node, pnpm, and the install as three separate steps.
`voidzero-dev/setup-vp` does all three from the files the repo already
pins, so CI follows the same Vite+ toolchain contributors run locally.
```diff
- name: Checkout repository
- - name: Set up pnpm # pnpm/action-setup
- - name: Set up Node.js # actions/setup-node, .node-version
- - name: Install package and dependencies
- run: pnpm install --frozen-lockfile
+ - name: Set up Vite+ and install dependencies
+ uses: voidzero-dev/setup-vp@68f39c78 # v1.21.2
+ with:
+ cache: true
+ run-install: |
+ - args: ['--frozen-lockfile']
- name: Check for lockfile drift # unchanged
- name: Run type, lint, and format checks
- name: Run package tests
+ - name: Build packages
+ run: pnpm build
```
With no version inputs, setup-vp resolves:
- **Vite+** from the `vite-plus` catalog entry (1.1.0)
- **Node** from `.node-version`
- **pnpm** from `packageManager`, including its `+sha512` hash
The new build step catches a broken `vite build` before the Docker
workflow does. `docs/development.md` drops the `pnpm/action-setup`
upgrade notes and now says Vite+ checks the pnpm hash as well.
## Evidence
**Before:** setup-node and pnpm/action-setup installed the toolchain,
and CI never ran `pnpm build`.
**After:** [run
38640754820](https://github.com/aws/graph-explorer/actions/runs/38640754820)
passed every step. Its log shows `Resolved Vite+ version '1.1.0' from
package.json`, Node `v24.21.0`, and `Done in 13s using pnpm v12.8.1`. It
also saved the dependency cache.
I ran two more checks:
- **Install refuses a stale lockfile, even without the flag.** A
throwaway branch with a stale lockfile and `run-install` left at its
default failed with `ERR_PNPM_OUTDATED_LOCKFILE`. The explicit
`--frozen-lockfile` stays anyway, so the guarantee doesn't depend on
that default.
- **A wrong pnpm hash fails.** Run locally with a corrupted
`packageManager` hash, `vp install` stops with `Hash mismatch for
pnpm@12.8.1`.
The job took 5m 0s on a cold cache, against 3m 52s for the last `main`
run. Install took 20s, and the new build step took 10s.
## Merge Danger
**Door:** two-way
**Impact:** CI
The dependency cache key changes once. Dependabot's existing `actions`
group will bump setup-vp.
## Related
- Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary Before `tsc` can go, we need to know whether Vite+'s type check catches everything it does. This turns on `lint.options.typeCheck`, so `vp check` and `vp lint` also report TypeScript errors through tsgolint. `pnpm checks` still runs `tsc` afterwards, so CI runs both side by side until [Retire tsc now that vp check type checks (#2420)](#2420) lands. ```diff options: { typeAware: true, + typeCheck: true, }, ``` `AGENTS.md` and `docs/development.md` no longer say `vp check` skips type checks. ## Evidence I planted each error below in a new or existing file, then ran `vp lint` and `pnpm check:types`. Both exit 1, with the same TypeScript code, for: - **All 3 packages:** a plain type error (TS2322), an implicit `any` (TS7006), an unused parameter and an unused local (TS6133, even with `no-unused-vars` disabled) - **graph-explorer:** `Object.groupBy` outside `lib: ES2023` (TS2550), a bad `@/` or `@shared/` path (TS2307), a `.tsx` prop type error, and a type error in a `.test.ts` file - **shared:** `Promise.withResolvers` outside `lib` (TS2550), a `.ts` import without `allowImportingTsExtensions` (TS5097), a missing `override` (TS4114), an `enum` under `erasableSyntaxOnly` (TS1294), and unreachable code - **proxy server:** an extensionless relative import under `nodenext` (TS2835) - **Config files:** a type error in the root and graph-explorer `vite.config.ts` `vp check` also catches a type error in `packages/shared/vite.config.ts` and `packages/graph-explorer-proxy-server/vite.config.ts`. `tsc` misses both, because no tsconfig includes those files. **Timing:** `vp check` takes 12.8s for the whole repo, with lint and types together in 8.7s of that. `pnpm check:types` takes 3.4s. The pre-commit hook on a single file takes 3 to 6s whether `typeCheck` is on or off. ## Merge Danger **Door:** two-way **Impact:** contributors Type errors now also fail the pre-commit hook for the files being committed. ## Related - Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary Before `tsc` can go, we need to know whether Vite+'s type check catches everything it does. This turns on `lint.options.typeCheck`, so `vp check` and `vp lint` also report TypeScript errors through tsgolint. `pnpm checks` still runs `tsc` afterwards, so CI runs both side by side until [Retire tsc now that vp check type checks (#2420)](#2420) lands. ```diff options: { typeAware: true, + typeCheck: true, }, ``` `AGENTS.md` and `docs/development.md` no longer say `vp check` skips type checks. ## Evidence I planted each error below in a new or existing file, then ran `vp lint` and `pnpm check:types`. Both exit 1, with the same TypeScript code, for: - **All 3 packages:** a plain type error (TS2322), an implicit `any` (TS7006), an unused parameter and an unused local (TS6133, even with `no-unused-vars` disabled) - **graph-explorer:** `Object.groupBy` outside `lib: ES2023` (TS2550), a bad `@/` or `@shared/` path (TS2307), a `.tsx` prop type error, and a type error in a `.test.ts` file - **shared:** `Promise.withResolvers` outside `lib` (TS2550), a `.ts` import without `allowImportingTsExtensions` (TS5097), a missing `override` (TS4114), an `enum` under `erasableSyntaxOnly` (TS1294), and unreachable code - **proxy server:** an extensionless relative import under `nodenext` (TS2835) - **Config files:** a type error in the root and graph-explorer `vite.config.ts` `vp check` also catches a type error in `packages/shared/vite.config.ts` and `packages/graph-explorer-proxy-server/vite.config.ts`. `tsc` misses both, because no tsconfig includes those files. **Timing:** `vp check` takes 12.8s for the whole repo, with lint and types together in 8.7s of that. `pnpm check:types` takes 3.4s. The pre-commit hook on a single file takes 3 to 6s whether `typeCheck` is on or off. ## Merge Danger **Door:** two-way **Impact:** contributors Type errors now also fail the pre-commit hook for the files being committed. ## Related - Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 14, 2026
## Summary Now that `vp check` type checks, the `tsc` scripts run the same check a second time. This removes them, so `pnpm checks` is `vp check`. ```diff - "check:types": "pnpm -r --include-workspace-root --parallel --stream run typecheck", - "typecheck": "tsc --noEmit", - "checks": "vp check && pnpm run check:types", + "checks": "vp check", ``` The `typecheck` script is also gone from all 3 packages. `AGENTS.md`, `REVIEW.md`, and `docs/agents/testing.md` now point at `pnpm checks` or the type check in `vp check` instead of `tsc`. The `typescript` dev dependency stays, because editors and tsgolint use it. Stacked on [Type check with vp check (#2419)](#2419), which has the parity evidence. ## Evidence **Before:** `pnpm checks` ran `vp check`, then `tsc --noEmit` in the root and each package. **After:** `pnpm checks` runs `vp check` only. A planted `const x: number = "s"` in `packages/shared` still fails it with TS2322, and a clean tree passes: `Found no warnings, lint errors, or type errors in 917 files`. ## Merge Danger **Door:** two-way **Impact:** contributors `pnpm check:types` and the package `typecheck` scripts no longer exist. Use `pnpm checks`. ## Related - Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 16, 2026
## Summary
The image was built in one stage. It installed everything, built,
deleted `node_modules`, reinstalled production dependencies in place,
then stripped npm, pnpm and corepack back out. Splitting it into stages
gives the same image without the cleanup pass, and production
dependencies get a layer that is reused until a manifest changes. Both
build stages and the runtime stay on the same pinned Amazon Linux 2023
snapshot.
```text
os amazonlinux snapshot, NODE_VERSION
├── toolchain + Node.js, corepack, pnpm
│ ├── build pnpm install, pnpm build, drop node_modules
│ └── deps manifests only, pnpm install --prod
└── runtime + openssl, minus python3/dnf/yum
node binary and its LICENSE from toolchain
node_modules from deps, then the app tree from build
```
The runtime never gets npm, pnpm or corepack, so nothing has to be
uninstalled. `test_build_docker.yml` now also starts the image in
notebook mode on 9250 and over HTTPS on 443, in addition to the plain
HTTP run on 80.
## Evidence
Old and new images were each built from a clean checkout of `main` and
compared:
- **Config:** `ExposedPorts`, `Entrypoint`, `WorkingDir`, `User`,
`PATH`, `NODE_VERSION` and `HOME` are identical. `VP_GIT_HOOKS` now
lives only in the build stage, since nothing runs git at runtime.
- **Files:** `/graph-explorer` has the same 41,681 `node_modules`
entries. The app tree matches too, except for 4 npm log files the old
image carried in `.npm/`.
- **Size:** 875 MB, down from 984 MB.
- **Runs:** both images answer `/status` over HTTP on 80, in notebook
mode on 9250, and over HTTPS on 443.
- **Upgrades:** state written by the published 3.3.0 image works
unchanged on the new one. A mounted `CONFIGURATION_FOLDER_PATH` folder
with a user `.env` starts and serves the same `/defaultConnection`. A
`cert-info` named volume serves the same certificate, matched by SHA-256
fingerprint, without `HOST`.
- **Config and certs:** against the current `main` image, a mounted
`config.json` (read-write and read-only) produces identical `.env`,
`defaultConnection.json` and `/defaultConnection`. A config folder ends
up with identical contents, and bind-mounted user certificates are
served the same way.
- **Checks:** Trivy reports no HIGH or CRITICAL findings on either
image. In the new image, `node --version` is `v24.21.0`, `openssl` is
present, and npm, pnpm, corepack, python3, yum and dnf are absent.
## Merge Danger
**Door:** two-way
**Impact:** Docker image
The published image has the same contents and entrypoint, so users and
the notebook setup see no change. A failure would show up at container
start, which the 3 `/status` runs check.
## Related
- Related to #2305
kmcginnes
added a commit
that referenced
this pull request
Oct 18, 2026
## Summary The Dockerfile pinned Node.js a second time in `ENV NODE_VERSION`, downloaded it with `curl | tar` and no checksum, and installed pnpm through a pinned Corepack. The build and deps stages now run in the official Vite+ image. It installs the Node.js in `.node-version` and the pnpm in `packageManager`, verifies both, and the runtime stays on the same Amazon Linux 2023 snapshot. ```diff -FROM amazonlinux:2023.… AS os -ENV NODE_VERSION=24.21.0 -FROM os AS toolchain # curl nodejs.org | tar, npm i -g corepack@0.36.0 +FROM ghcr.io/voidzero-dev/vite-plus:1.1.0@sha256:… AS toolchain FROM toolchain AS build vp install, vp run build, export node + LICENSE FROM toolchain AS deps vp install --prod -FROM os AS runtime +FROM amazonlinux:2023.… AS runtime ``` `.node-version` is now the only Node.js pin the image uses. `test_build_docker.yml` checks that the image's `node --version` matches it. `docs/development.md` and the Dependabot comments drop the Corepack and `NODE_VERSION` notes. ## Evidence **Before:** the image's Node.js came from `ENV NODE_VERSION`, with no signature or checksum check, and pnpm came from Corepack 0.36.0. **After:** the image builds with `Done in 15.7s using pnpm v12.8.1`. The new CI step reports `✓ node v24.21.0`, which matches `.node-version`. Compared with an image built from current `main`: - **Contents:** every file under `/graph-explorer` and `/usr/local` is byte-identical, with the same owners and modes. The only exceptions are `Dockerfile` and pnpm's install metadata. `/usr/local/bin/node` has the same SHA-256, so Vite+ fetched the same official build. - **Config:** `ExposedPorts`, `Entrypoint`, `WorkingDir`, `User`, `PATH` and `HOME` are unchanged. `NODE_VERSION` is gone from the image environment. - **Size:** 875 MB, the same as before. - **Trivy:** no HIGH or CRITICAL findings. **Verified live:** I ran both images through every documented deployment path and compared the results: - **Startup:** both answer `/status` over HTTP on 80, in notebook mode on 9250, and over HTTPS on 443. - **Config:** a mounted `config.json`, read-write and read-only, gives identical `.env`, `defaultConnection.json` and `/defaultConnection`. - **Config folder:** a `CONFIGURATION_FOLDER_PATH` folder with a user `.env` ends up with identical contents. - **Certificates:** bind-mounted user certificates are served the same way, and a restart keeps the same certificate. - **Upgrade from 3.3.0:** a config folder and a `cert-info` named volume written by the published 3.3.0 image work unchanged on the new image. The volume serves the same certificate fingerprint. - **Stop:** `docker stop` takes 0.13s and exits 0. ## Merge Danger **Door:** two-way **Impact:** Docker image The shipped image has the same contents and behavior. One environment variable disappears: `NODE_VERSION` is no longer set inside the container. Nothing in this repo reads it, and it was only ever set to report the build's Node.js version. Builds now pull `ghcr.io/voidzero-dev/vite-plus`, pinned by digest, in addition to the Amazon Linux image. ## Related - Related to #2305 - Related to #2422
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the toolchain to Vite+ 1.1 using
vp migrate, then finishes by hand what it left. The app, the proxy server, and the Docker image behave the same. Only contributor tooling changes.What
vp migratedid (first commit):vite.config.tsoxlint,oxfmt, andoxlint-tsgolintwithvite-plus, pinned through a pnpm catalog.vitenow points at@voidzero-dev/vite-plus-corevitestimports tovite-plus/testand droppedvitestfrom every manifestWhat I finished by hand (second commit):
minimumReleaseAgeExcludelist the migrator added. It exempted vite-plus, vitest, and the oxc packages from our 24h release-age gate.stagedblock and.vite-hooks/pre-commit.vp configwon't replace acore.hooksPathit doesn't own. Sopreparefirst unsets it when it points at Husky, which means existing clones pick up the new hooks on their nextpnpm install:husky, and|| cd .keeps it portable to cmd. It can go after a release or two.ENV VP_GIT_HOOKS=0, because the image has nogit, andvp configfails the install where Husky skipped quietly.vite-plusgroup, because the catalog aliasesviteto@voidzero-dev/vite-plus-coreat the vite-plus version.AGENTS.md: allows runningvpsubcommands directly.Review follow-ups (third commit):
test.projectsmoved intovite.config.ts, and the proxy-server and sharedvitest.config.tsfiles are nowvite.config.tstypeChecklint option the migrator added.tscinpnpm check:typesstays the one type check, sopnpm checksdoesn't type-check twice and the pre-commit hook doesn't start blocking on type errors.github/dependabot.ymlandpnpm-workspace.yaml: vite-plus bumps carry Vite, Vitest, oxlint, and oxfmt fixes, andvp migratere-adds the release-age exclusions on every upgradedocs/agents/testing.mdimports fromvite-plus/test.docs/development.mdgains a Tooling section and drops apnpm add -D vitestexample.REVIEW.mdnamesvp lintandvp fmtSecond review round (fourth commit):
test:watchisvp test watch, becausevp testruns once by default wherevitestwatchedpackages/graph-explorerdeclarestypescript^7.0.2 like the root, sovite-plusand Vitest resolve to one copy instead of two.cva's optionaltypescript <6peer is now reported as unmet, the same way the root's@typescript-eslintpeers already were. Types and tests passstagedis the Vite+ default,"*": "vp check --fix", instead of the two globs ported from lint-staged. Every file typevp fmtsupports (Markdown, CSS, HTML, JSON, YAML, TS) is formatted, lint fixes run on JS/TS, unsupported files such as images pass through, and fmt and lint ignore patterns still applyAGENTS.mdsaysvp checkskips the type check, anddocs/development.mdcovers acore.hooksPaththat isn't Husky'sTool versions: vite-plus 1.1.0 bundles vitest 5.0.3, oxlint 1.87.0, and oxfmt 0.72.0, each at or ahead of what
mainpins today.vitestis no longer a direct dependency anywhere. Vite+ bundles it and re-exports it asvite-plus/test, so it moves in lockstep withvite-plus.Evidence
pnpm checkspasses. Test files with deliberate violations still trip type-aware rules (switch-exhaustiveness-check) and JS plugins (react-compiler/set-state-in-render), so the merged lint config has parity.pnpm testpasses: 251 files, 3343 testspnpm buildpassesdocker buildpasses, and the running container returns 200 on/explorer/pnpm devserves the app with the React Compiler transform applied.vite-hooks/pre-commitrunsvp lint --fixandvp fmton the staged filespnpm installfrom agit archiveextract (no.git) passescore.hooksPath=.husky/_gets.vite-hooks/_afterpnpm installMerge Danger
Door: two-way
A revert restores the old tooling. Contributors then need one
pnpm installso Husky resets the hooks path.Blast Radius: contributors
Release notes for contributors:
pnpm installafter pulling. It moves your git hooks from Husky to Vite+.VoidZero.vite-plus-extension-pack), oroxc-zedfor Zed.vpsubcommands (vp test,vp lint,vp fmt,vp check) now work directly.core.hooksPathis shared by every worktree of a clone. While some worktrees are still on older branches, installing on this branch and on an older branch will flip the path back and forth, and the hook only runs in worktrees that match the current value. It settles once every worktree is onmain.The shipped bundle is now built by
vite-plus-coreinstead ofvite8.3. The build and Docker smoke tests above cover that swap.